/**
  ******************************************************************************
  * @file
  * @brief
  * @author taoye
  * @version V1.0.0
  * @date 2021/01/01
  ******************************************************************************
  */


/* Includes ------------------------------------------------------------------*/
#include "common_f4.h"
/* Private defines -----------------------------------------------------------*/

/* Private Struct  -----------------------------------------------------------*/


/* Private enum    -----------------------------------------------------------*/


/* Private Variable  ---------------------------------------------------------*/
//Pointer
static GPIO_TypeDef *Gpio_port[]={
    GPIOA,
    GPIOB,
    GPIOC,
    GPIOD,
    GPIOE,
    GPIOF,
    GPIOG,
};

static uint32_t Gpio_portrcc[]={
    RCC_AHB1Periph_GPIOA,
    RCC_AHB1Periph_GPIOB,
    RCC_AHB1Periph_GPIOC,
    RCC_AHB1Periph_GPIOD,
    RCC_AHB1Periph_GPIOE,
    RCC_AHB1Periph_GPIOF,
    RCC_AHB1Periph_GPIOG,
};

static uint16_t Gpio_pin[]={
    GPIO_Pin_0,
    GPIO_Pin_1,
    GPIO_Pin_2,
    GPIO_Pin_3,
    GPIO_Pin_4,
    GPIO_Pin_5,
    GPIO_Pin_6,
    GPIO_Pin_7,
    GPIO_Pin_8,
    GPIO_Pin_9,
    GPIO_Pin_10,
    GPIO_Pin_11,
    GPIO_Pin_12,
    GPIO_Pin_13,
    GPIO_Pin_14,
    GPIO_Pin_15,
};

static uint8_t Gpio_pinsource[]={
    GPIO_PinSource0,
    GPIO_PinSource1,
    GPIO_PinSource2,
    GPIO_PinSource3,
    GPIO_PinSource4,
    GPIO_PinSource5,
    GPIO_PinSource6,
    GPIO_PinSource7,
    GPIO_PinSource8,
    GPIO_PinSource9,
    GPIO_PinSource10,
    GPIO_PinSource11,
    GPIO_PinSource12,
    GPIO_PinSource13,
    GPIO_PinSource14,
    GPIO_PinSource15,
};
//Array

//Const

/* Private function prototypes -----------------------------------------------*/

/***********************************************************************************
 * @brief 
 * ex:
 * @par  
 * None
 * @par 
 * None
 * @retval 
 **********************************************************************************/
int Common_CheckGpio(const char *gpio_name, GPIO_TypeDef **port, uint16_t *pin, uint32_t *portrcc, uint8_t *source)
{
    // 在有些情况，个别引脚没有使用到，不能回复错误
    if(gpio_name == NULL){
        return 0;
    }
    if(strlen(gpio_name) > 3 || strlen(gpio_name) < 2){
        return -1;
    }
    if(gpio_name[0] < 'A' || gpio_name[0] > 'G'){
        return -1;
    }
    
    uint8_t port_id = gpio_name[0] - 'A';
    uint8_t pin_id  = atoi(&gpio_name[1]);
    
    if(port_id > (sizeof(Gpio_port) / sizeof(GPIO_TypeDef *) - 1)){
        return -1;
    }
    if(pin_id > (sizeof(Gpio_pin) / sizeof(uint16_t) - 1)){
        return -1;
    }
    
    *portrcc        = Gpio_portrcc[port_id];
    *port           = Gpio_port[port_id];
    *pin            = Gpio_pin[pin_id];
    *source         = Gpio_pinsource[pin_id];

    return 0;
}
/***********************************************************************************
 * @brief 
 * ex:
 * @par  
 * None
 * @par 
 * None
 * @retval 
 **********************************************************************************/
int Common_Gpio_AFConfig(const char *gpio_name, uint8_t GPIO_AF, GPIOPuPd_TypeDef pupd)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    
    // 在有些情况，个别引脚没有使用到，不能回复错误
    if(gpio_name == NULL){
        return 0;
    }
    if(strlen(gpio_name) > 3 || strlen(gpio_name) < 2){
        return -1;
    }
    if(gpio_name[0] < 'A' || gpio_name[0] > 'G'){
        return -1;
    }
    
    uint8_t port_id = gpio_name[0] - 'A';
    uint8_t pin_id  = atoi(&gpio_name[1]);
    
    if(port_id > (sizeof(Gpio_port) / sizeof(GPIO_TypeDef *) - 1)){
        return -1;
    }
    if(pin_id > (sizeof(Gpio_pin) / sizeof(uint16_t) - 1)){
        return -1;
    }

        /* 使能外设时钟 */
    RCC_AHB1PeriphClockCmd(Gpio_portrcc[port_id], ENABLE);
    /* 管脚初始化 */
    GPIO_InitStructure.GPIO_Pin     = Gpio_pin[pin_id];
    GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType   = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_PuPd    = pupd;
    GPIO_Init(Gpio_port[port_id], &GPIO_InitStructure);
    /* 管脚重分配 */
    GPIO_PinAFConfig(Gpio_port[port_id], Gpio_pinsource[pin_id], GPIO_AF);

    return 0;
}
/***********************************************************************************
 * @brief 
 * ex:
 * @par  
 * None
 * @par 
 * None
 * @retval 
 **********************************************************************************/
void SoftDelay_us(uint32_t us)
{
    for(uint32_t i=0; i<us; i++){
        for(uint32_t j=0; j<30; j++){
            ;
        }
    }
}
/***********************************************************************************
 * @brief 
 * ex:
 * @par  
 * None
 * @par 
 * None
 * @retval 
 **********************************************************************************/
void SoftDelay_ms(uint32_t ms)
{
    for(uint32_t i=0; i<ms; i++){
        SoftDelay_us(1000);
    }
}

